<!--
* @description 百度地图
* @fileName index.vue
* @author zero_fsc
* @date 2020/06/29 10:17:03
!-->
<template>
  <div class="content">
    <div :id="id" class="container"></div>
    <input type="text" v-show="!readOnly" :id="searchId" class="search" :placeholder="placeholder">
  </div>
</template>

<script>
import {
  createRandomId
} from '@/utils'
export default {
  props: {
    lng: {
      type: null,
      default: ''
    },
    lat: {
      type: null,
      default: ''
    },
    addr: {
      type: String,
      default: ''
    },

    readOnly: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: '请输入搜索条件'
    }
  },
  data () {
    return {
      map: '',
      id: createRandomId(),
      searchId: createRandomId(),
      // 缩放倍数
      zoom: 16
    }
  },

  mounted () {
    setTimeout(() => {
      this.initMap()
    }, 1000)
  },

  methods: {
    /*
    * @description 初始化百度地图
    * @fileName index.vue
    * @author zero_fsc
    * @date 2020/06/29 10:26:06
    */
    initMap () {
      const _this = this
      this.map = new BMap.Map(this.id)
      // 根据浏览器定位当前位置
      !this.lng && !this.lat ? _this.getPositionByBrow() : _this.initMarker([+this.lng, +this.lat])
      // 添加放大缩小模式
      this.map.enableScrollWheelZoom(true)
      // 添加控件 工具条 比例尺
      this.map.addControl(
        new BMap.NavigationControl({
        // 左上角
          anchor: BMAP_ANCHOR_TOP_LEFT,
          // Large类型
          type: BMAP_NAVIGATION_CONTROL_LARGE,
          // 启动显示定位
          enableGeolocation: true
        })
      )
      // 添加定位控件
      const geolocationControl = new BMap.GeolocationControl()
      // 定位成功
      geolocationControl.addEventListener('locationSuccess', ({ point }) => {
        // 清除标点 在初始化标点 使其成为新点
        _this.clearMarker()
        _this.initMarker([point.lng, point.lat])
      })
      // 定位失败
      geolocationControl.addEventListener('locationError', e => {
        console.log('定位失败', e.message)
      })
      this.map.addControl(geolocationControl)
      // 添加搜索控件
      _this.initInput()
    },

    /*
    * @description 根据浏览器获取定位
    * @fileName index.vue
    * @author zero_fsc
    * @date 2020/06/29 15:44:11
    */
    getPositionByBrow () {
      const _this = this
      const geolocation = new BMap.Geolocation()
      geolocation.getCurrentPosition(function ({ point, ...value }) {
        if (this.getStatus() === BMAP_STATUS_SUCCESS) {
          _this.initMarker([point.lng, point.lat])
        } else {
          console.log('获取当前坐标定位失败' + this.getStatus())
        }
      })
    },

    /*
    * @description 设置拖拽的marker标点
    * @fileName index.vue
    * @author zero_fsc
    * @date 2020/06/29 11:11:00
    */
    initMarker (position) {
      const that = this
      const point = new BMap.Point(position[0], position[1])
      // 逆地址解析
      that.getMarkerPosition(position[0], position[1])
      this.map.centerAndZoom(point, that.zoom)
      // 创建marker点
      const marker = new BMap.Marker(point)
      // marker点注入地图
      this.map.addOverlay(marker)
      // 用于readOnly --- marker点不可拖拽
      this.readOnly ? marker.disableDragging() : marker.enableDragging()
      marker.addEventListener('dragend', getPosition)
      // 获取拖拽后的坐标
      function getPosition () {
        // 拖拽后的坐标
        const { lng, lat } = marker.getPosition()
        // 逆地址解析
        that.getMarkerPosition(lng, lat)
      }
    },

    /*
    * @description 获取拖拽后marker点的坐标
    * @fileName index.vue
    * @author zero_fsc
    * @date 2020/06/29 11:23:55
    */
    getMarkerPosition (lng, lat) {
      const point = new BMap.Point(lng, lat)
      this.map.centerAndZoom(point, this.zoom)
      const geocoder = new BMap.Geocoder({
        extensions_town: true
      })
      geocoder.getLocation(point, ({ addressComponents, point }) => {
        // 详细地址
        let addr = ''
        addr += addressComponents.province
        addr += addressComponents.city
        addr += addressComponents.district
        addr += addressComponents.street
        addr += addressComponents.streetNumber
        this.$emit('update:lng', point.lng)
        this.$emit('update:lat', point.lat)
        this.$emit('update:addr', addr)
      })
    },

    /*
    * @description 初始化搜索
    * @fileName index.vue
    * @author zero_fsc
    * @date 2020/06/29 16:13:08
    */
    initInput () {
      const _this = this
      const autoComplete = new BMap.Autocomplete({
        'input': this.searchId,
        'location': this.map
      })
      autoComplete.addEventListener('onconfirm', function (e) {
        var address = e.item.value
        const addr = address.province + address.city + address.district + address.street + address.business
        _this.getPositionByInput(addr)
      })
    },

    /*
    * @description 搜索框搜索定位
    * @fileName index.vue
    * @author zero_fsc
    * @date 2020/06/29 16:30:35
    */
    getPositionByInput (addr) {
      const _this = this
      // 清除marker点
      this.clearMarker()
      // 添加智能搜索控件
      const localSearch = new BMap.LocalSearch(this.map, {
        onSearchComplete: complete
      })

      function complete () {
        // 点击搜索的位置后的定位
        const position = localSearch.getResults().getPoi(0).point
        _this.initMarker([position.lng, position.lat])
      }
      localSearch.search(addr)
    },

    /*
    * @description 清除marker标点 --- 主要用于点击定位当前位置时
    * @fileName index.vue
    * @author zero_fsc
    * @date 2020/06/29 16:05:38
    */
    clearMarker () {
      this.map.clearOverlays()
    }
  }
}

</script>
<style lang="scss" scoped>
.content {
  position: relative;
  width: 30em !important;
  height: 50em;
  .container {
    width: 100%;
    height: 100%;
  }
  .search{
    position: absolute;
    top: 15px;
    left: 80px;
    width: 250px;
    height: 32px;
    border-radius: 50px;
    border: none;
    padding: 0 24px;
    &:focus {
      border: 0;
      outline: none;
      border-style: none;
      border-radius: 50px;
      border: 1px solid #409EFF;
    }
  }
}
</style>
